package com.xusheng.cli.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xusheng.cli.common.exception.ServiceException;
import com.xusheng.cli.core.util.CommonUtils;
import com.xusheng.cli.entity.paymentChannelModule.PaymentChannel;
import com.xusheng.cli.entity.rechargeModule.Recharge;
import com.xusheng.cli.service.PaymentChannelService;
import com.xusheng.cli.service.YzfPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@Service("YzfPayService")
@Slf4j
public class YzfPayServiceImpl implements YzfPayService {
    @Resource
    private PaymentChannelService paymentChannelService;

    @Override
    public String createOrder(Recharge order, HttpServletRequest request) {
        String returnUrl = request.getScheme() + "://" + request.getServerName();
        PaymentChannel paymentChannel = paymentChannelService.getById(order.getPaymentId());
        HttpResponse httpResponse = orderCreate(order, returnUrl, paymentChannel);
        JSONObject result = JSONUtil.parseObj(httpResponse.body());
        String ret_code = result.getStr("code");
        String ret_msg = result.getStr("msg");

        String orderCreateUrl = "";
        if ("1".equals(ret_code)) {
            // app
            if (result.containsKey("payurl")) {
//                orderCreateUrl = "alipays://platformapi/startApp?appId=20000067&url=" + URLEncoder.encode(result.getJSONObject("data").getStr("qRCodeUrl"));
                orderCreateUrl = result.getStr("payurl");
            } else if (result.containsKey("qrcode")) {
                // pc
                orderCreateUrl = result.getStr("qrcode");
            }
            if (StrUtil.isEmpty(orderCreateUrl)) {
                log.error("商户订单号[{}] 发卡下单失败 请求接口成功，接口返回报文 url为空", order.getOrderNumber());
                throw new ServiceException("下单失败，请稍后重试！");
            }
        } else {
            log.error("商户订单号[{}] 发卡下单失败 请求接口成功，接口返回失败 Code:{} Message:{}", order.getOrderNumber(), ret_code, ret_msg);
            throw new ServiceException("下单失败，请稍后重试！失败描述：" + ret_msg);
        }
        return orderCreateUrl;
    }

    private HttpResponse orderCreate(Recharge order, String returnUrl, PaymentChannel paymentChannel) {
        log.info("+++++++++++++++++++++++{}", returnUrl);
        Map<String, String> reqParam = new TreeMap<>();
        reqParam.put("pid", paymentChannel.getMerchantNumber());
        reqParam.put("type", paymentChannel.getType().getKey());
        reqParam.put("out_trade_no", order.getOrderNumber());
        reqParam.put("notify_url", returnUrl.concat("/video-platform/open/v1/yzfpay/notify"));
        reqParam.put("money", order.getRechargeAmount().toString()); // 单位：元
        reqParam.put("return_url", returnUrl);
        reqParam.put("clientip", CommonUtils.getClientIp());
        reqParam.put("device", paymentChannel.getChannel() == 0 ? "pc" : "mobile");
        reqParam.put("name", "左手TV");
        String sign = getSign(reqParam, paymentChannel.getSecret());
        reqParam.put("sign", sign);
        System.out.println(JSONUtil.toJsonStr(reqParam));
        Map<String, String> heads = new HashMap<>();

        heads.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        HttpResponse response = HttpRequest.post(paymentChannel.getHost() + "/mapi.php")
                .headerMap(heads, false)
                .form(new HashMap<String, Object>(reqParam))
                .timeout(5 * 60 * 1000)
                .execute();
        log.info("返回结果========{}", response);
        return response;
    }

    private String getPayCode(Integer payMode) {
        if (payMode == 3) {
            return "wx_scan";
        }
        return "ali_scan";

    }

    public static String getSign(Map<String, String> reqParam, String key) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : reqParam.entrySet()) {
            if (!"code".equalsIgnoreCase(entry.getKey()) && StrUtil.isNotEmpty(entry.getValue())) {
//                sb.append(entry.getValue()).append("&");
                sb.append(entry.getKey() + "=" + entry.getValue()).append("&");
            }
        }
        // 去掉最后一个&
        String signOriginStr = sb.toString();
        signOriginStr = signOriginStr.substring(0, signOriginStr.length() - 1);
        signOriginStr += key;
        log.info("签名原文:{}", signOriginStr);
        String sign = null;
        try {
            sign = DigestUtils.md5Hex(signOriginStr.getBytes("UTF-8"));
        } catch (Exception e) {
            log.error("字符串进行MD5加密发生{}异常，具体错误描述:{}", e.getClass().getName(), e.getMessage());
        }

        if (StrUtil.isEmpty(sign)) {
            return null;
        }
        log.info("实际签名:{}", sign);
        return sign;
    }

    public static void main(String[] args) {
        Map<String, String> reqParam = new TreeMap<>();
        reqParam.put("out_trade_no", "20160806151343349");
        reqParam.put("pid", "1000");
        reqParam.put("notify_url", "/video-platform/open/v1/yzfpay/notify");
//        reqParam.put("type", "wxpay");
        reqParam.put("type", "wxpay");
        reqParam.put("money", "1"); // 单位：分
        reqParam.put("return_url", "http://xxxx.com/index");
        reqParam.put("clientip", "10.101.10.10");
        reqParam.put("device", "mobile");
        reqParam.put("name", "1区");
        String sign = getSign(reqParam, "QgZWsAvzfyMMuMvpNt4Mkp0DuVU8dcgg");
        reqParam.put("sign", sign);
        System.out.println(JSONUtil.toJsonStr(reqParam));
        Map<String, String> heads = new HashMap<>();

        heads.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

        HttpResponse response = HttpRequest.post("https://aaa.qtds.cc/mapi.php")
                .headerMap(heads, false)
                .form(new HashMap<String, Object>(reqParam))
                .timeout(5 * 60 * 1000)
                .execute();
        log.info("返回结果=》{}", response);

    }
}
